home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copy.cmm
- *
- * A copy script for the CEnvi shell. It does what the DOS copy
- * command does.
- */
-
- #include "Netware.lib"
-
- usage()
- {
- printf("Use the COPY command to copy one or more file(s) from one\n");
- printf("location to another.\n");
- printf("Syntax:\n");
- printf(" COPY [drive][path] filename [+][,,][drive][path][filename] [/V]\n");
- printf("where:\n");
- printf(" drive/path/filename Specifies the file to be copied.\n");
- printf(" + Combines or appends files.\n");
- printf(" + ,, Updates the time and date of a file.\n");
- printf(" drive/path/filename Specifies the target file name.\n");
- printf(" /V Verifies that sectors written to the target\n");
- printf(" disk are recorded properly.\n");
- exit(EXIT_FAILURE);
- }
-
- /* ---------------------------------------------------------------------- */
-
- /*
- * Some DOS functions
- */
- SetFileAttributes(pFileName,pAttributes)
- {
- lReg.ah = 0x43;
- lReg.al = 1;
- lReg.cx = pAttributes;
- if !defined(_DOS32_)
- lReg.ds = segment(pFileName), lReg.dx = offset(pFileName);
- else
- lReg.dx = pointer(pFileName);
- return interrupt(0x21,lReg);
- }
-
- SetFileDateAndTime(pFileName,pTime)
- {
- lSuccess = False;
- // Open file to get a handle
- lReg.ah = 0x3D;
- lReg.al = 0x42;
- if !defined(_DOS32_)
- lReg.ds = segment(pFileName), lReg.dx = offset(pFileName);
- else
- lReg.dx = pointer(pFileName);
- if ( interrupt(0x21,lReg,lRegout) ) {
- lHandle = lRegout.ax;
- // write date to file
- undefine(lReg);
- lReg.ah = 0x57;
- lReg.al = 1;
- lReg.bx = lHandle;
- lTm = localtime(pTime);
- lReg.cx = (lTm.tm_sec / 2)
- | (lTm.tm_min << 5)
- | (lTm.tm_hour << 11);
- lReg.dx = lTm.tm_mday
- | ((lTm.tm_mon+1) << 5)
- | ((lTm.tm_year-80) << 9);
- lSuccess = interrupt(0x21,lReg);
- // close file
- undefine(lReg);
- lReg.ah = 0x3E;
- lReg.bx = lHandle;
- interrupt(0x21,lReg);
- }
- return lSuccess;
- }
-
- DOSTimeFromCalendar(time)
- {
- dos = DOSTimeStructFromCalendar(time);
- return (dos.time<<16) | (dos.date);
- }
-
- DOSTimeStructFromCalendar(time)
- {
- tm = localtime(time);
- dos.time = (tm.tm_sec/2) | (tm.tm_min<<5) | (tm.tm_hour<<11);
- dos.date = tm.tm_mday | ((tm.tm_mon+1)<<5) | ((tm.tm_year-80)<<9);
- return dos;
- }
-
- GMDOSTimeStructFromCalendar(time)
- {
- tm = gmtime(time);
- dos.time = (tm.tm_sec/2) | (tm.tm_min<<5) | (tm.tm_hour<<11);
- dos.date = tm.tm_mday | ((tm.tm_mon+1)<<5) | ((tm.tm_year-80)<<9);
- return dos;
- }
-
- #define GENERIC_WRITE 0x40000000
- #define FILE_SHARE_READ 0x01
- #define FILE_SHARE_WRITE 0x02
- #define OPEN_EXISTING 3
- #define INVALID_HANDLE_VALUE -1
-
- /* ---------------------------------------------------------------------- */
-
- verify = FALSE;
- source[0] = "";
- num_source = 0;
- target = "";
- doing_plus = FALSE;
- update_time = FALSE;
-
- parse_command_line(argc,argv)
- {
- for( i=1;i<argc;i++ )
- {
- if( argv[i][0]=='-' || argv[i][0]=='/' )
- {
- switch( toupper(argv[i][1]) )
- {
- default: usage();
- case 'V': verify = TRUE; break;
- }
- continue;
- }
- if( argv[i][0]=='+' )
- {
- if( doing_plus ) {
- printf("Already doing plus mode.\n");
- exit(EXIT_FAILURE);
- }
- if( num_source==0 ) {
- printf("You must specify a file, then you can use + to specify more.\n");
- exit(EXIT_FAILURE);
- }
- doing_plus = TRUE;
- if( argv[i][1] ) {
- argv[i]++;
- i--;
- }
- continue;
- }
- if( argv[i][0]==',' )
- {
- if( !doing_plus || argv[i][1]!=',' ) {
- printf("To update a file's time, use \"+ ,,\".\n");
- exit(EXIT_FAILURE);
- }
- update_time = TRUE;
- doing_plus = FALSE;
- continue;
- }
- // Have a filename
- if( num_source==0 || doing_plus ) {
- strcpy(source[num_source++],argv[i]);
- doing_plus = FALSE;
- continue;
- }
-
- if( target[0]!='\0' ) {
- printf("Too many target files specified.\n");
- exit(EXIT_FAILURE);
- }
- strcpy(target,argv[i]);
- }
- if( doing_plus ) { printf("Extraneous plus.\n"); exit(EXIT_FAILURE); }
- if( num_source==0 )
- { printf("No source file specified.\n"); exit(EXIT_FAILURE); }
- if( target[0]=='\0' ) target = ".";
- }
-
- /*
- * Copy a single file. When done, set the time to the old file's time
- * stamps if update_time not set
- */
- copy_file(source,target)
- {
- strcpy(src,FullPath(source));
- strcpy(tar,FullPath(target));
-
- if( !stricmp(src,tar) )
- {
- // Same file!
- if( update_time )
- {
- dir = Directory(target);
- if( dir==NULL || GetArraySpan(dir)>0 )
- {
- printf("Copy_file: error, target should be a single file.\n");
- return;
- }
-
- curtime = time();
- if( defined(_NWNLM_) )
- {
- tempcreate[0] = DOSTimeFromCalendar(curtime);
- tempaccess[0] = DOSTimeFromCalendar(curtime);
- tempdate[0] = DOSTimeFromCalendar(curtime);
- tempbackup[0] = DOSTimeFromCalendar(curtime);
-
- code = NLMLink("SetFileInfo", target, 0x06, dir[0].attrib,
- tempcreate,
- tempaccess,
- tempdate,
- tempbackup,
- dir[0].uid);
- if( code )
- printf("\nError setting attributes for file %s\n",target);
- return;
- }
- if( defined(_DOS_) || defined(_DOS32_) || defined(_WINDOWS_) )
- {
- SetFileDateAndTime(target,curtime);
- return;
- }
- if( defined(_NTCON_) || defined(_NTWIN_) )
- {
- newbuf = ""; SetArraySpan(newbuf,100);
-
- if( (handle = DynamicLink("KERNEL32","CreateFileA",STDCALL,target,
- GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
- NULL,OPEN_EXISTING,0,NULL))
- !=INVALID_HANDLE_VALUE)
- {
- dos = GMDOSTimeStructFromCalendar(time());
- if( !DynamicLink("KERNEL32","DosDateTimeToFileTime",STDCALL,
- dos.date,dos.time,newbuf) )
- {
- printf("Unable to convert to NT Time structure.\n");
- return;
- }
-
- if( !DynamicLink("KERNEL32","SetFileTime",STDCALL,handle,newbuf,
- newbuf,newbuf) )
- {
- err = DynamicLink("KERNEL32","GetLastError",STDCALL);
- printf("Unable to set new file time.\n",err);
- }
-
- if( !DynamicLink("KERNEL32","CloseHandle",STDCALL,handle) )
- printf("Unable to close the handle.\n");
- } else {
- printf("Unable to open the file to touch it.\n");
- }
- return;
- }
-
- if( defined(_OS2_) )
- {
- printf("Cannot set timestamps on OS/2 yet.\n");
- return;
- }
- }
- printf("Cannot copy file to itself.\n");
- return;
- }
-
-
- if( (fp = fopen(source,stricmp(source,"con")?"rb":"rt"))==NULL )
- {
- printf("Unable to open source file %s\n",source);
- return;
- }
- if( (fp2 = fopen(target,stricmp(target,"con")?"wb":"rt"))==NULL )
- {
- printf("Unable to open target file %s\n",target);
- fclose(fp);
- return;
- }
-
- buffer = ""; SetArraySpan(buffer,10000);
-
- while( 1 )
- {
- num = fread(buffer,9900,fp);
- if( num<1 ) break;
- fwrite(buffer,num,fp2);
- }
-
- fclose(fp2);
- fclose(fp);
-
- if( verify )
- {
- if( !stricmp(target,"con") || !stricmp(source,"con") )
- {
- printf("Cannot verify to or from the console.\n");
- return;
- }
- if( (fp = fopen(source,"rb"))==NULL )
- {
- printf("Unable to open source file %s\n",source);
- return;
- }
- if( (fp2 = fopen(target,"rb"))==NULL )
- {
- printf("Unable to write target file %s; check path is correct\n",target);
- fclose(fp);
- return;
- }
-
- buffer2 = ""; SetArraySpan(buffer2,10000);
-
- while( 1 )
- {
- num = fread(buffer,9900,fp);
- if( num<1 ) break;
- num2 = fread(buffer2,9900,fp2);
- if( num!=num2 || memcmp(buffer,buffer2,num) )
- {
- printf("File \"%s\" was copied incorrectly.\n",target);
- }
- }
-
- fclose(fp2);
- fclose(fp);
- }
-
- if( !update_time && stricmp(target,"con") )
- {
- dir = Directory(source);
- if( dir==NULL || GetArraySpan(dir)!=0 )
- {
- printf("Error, can no longer open source file!\n");
- return;
- }
-
- if( defined(_NWNLM_) )
- {
- tempcreate[0] = DOSTimeFromCalendar(dir[0].Create);
- tempaccess[0] = DOSTimeFromCalendar(dir[0].Access);
- tempdate[0] = DOSTimeFromCalendar(dir[0].Write);
- tempbackup[0] = DOSTimeFromCalendar(dir[0].Backup);
-
- code = NLMLink("SetFileInfo",
- target,
- 0x06,
- dir[0].attrib,
- tempcreate,
- tempaccess,
- tempdate,
- tempbackup,
- dir[0].uid);
- if( code )
- printf("\nError setting attributes for file %s\n",target);
- }
- if( defined(_DOS_) || defined(_DOS32_) || defined(_WINDOWS_) )
- {
- SetFileDateAndTime(target,dir[0].Create);
- SetFileAttributes(target,dir[0].attrib);
- }
- if( defined(_NTCON_) || defined(_NTWIN_) )
- {
- DynamicLink("KERNEL32","SetFileAttributesA",STDCALL,target,dir[0].attrib);
-
- FTimeDef.LowTime = UWORD32;
- FTimeDef.HightTime = UWORD32;
-
- if( (handle = DynamicLink("KERNEL32","CreateFileA",STDCALL,target,
- GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
- NULL,OPEN_EXISTING,0,NULL))
- !=INVALID_HANDLE_VALUE)
- {
- dos = GMDOSTimeStructFromCalendar(dir[0].Create);
- DynamicLink("KERNEL32","DosDateTimeToFileTime",STDCALL,
- dos.date,dos.time,FTimeDef,CreateFTime);
- dos = GMDOSTimeStructFromCalendar(dir[0].Access);
- DynamicLink("KERNEL32","DosDateTimeToFileTime",STDCALL,
- dos.date,dos.time,FTimeDef,AccessFTime);
- dos = GMDOSTimeStructFromCalendar(dir[0].Write);
- DynamicLink("KERNEL32","DosDateTimeToFileTime",STDCALL,
- dos.date,dos.time,FTimeDef,WriteFTime);
-
- if( !DynamicLink("KERNEL32","SetFileTime",STDCALL,handle,FTimeDef,CreateFTime,
- FTimeDef,AccessFTime,FTimeDef,WriteFTime) )
- {
- err = DynamicLink("KERNEL32","GetLastError",STDCALL);
- printf("Unable to set new file time.\n",err);
- }
-
- if( !DynamicLink("KERNEL32","CloseHandle",STDCALL,handle) )
- printf("Unable to close the handle.\n");
- } else {
- printf("Unable to open the file to touch it.\n");
- }
- return;
- }
-
- if( defined(_OS2_) )
- {
- printf("Cannot set time on OS/2 yet.\n");
- exit(EXIT_FAILURE);
- }
- }
- }
-
- copy_multiple(target)
- {
- if( (fp2 = fopen(target,"w"))==NULL )
- {
- printf("Unable to write target file %s; check path is correct.\n",target);
- return;
- }
-
- buffer = ""; SetArraySpan(buffer,1024);
- for( i=0;i<num_source;i++ )
- {
- files = Directory(source[i]);
- for( j=0;files && j<=GetArraySpan(files);j++ )
- {
- if( (fp = fopen(files[j].name,"r"))==NULL )
- {
- printf("Unable to open source file %s\n",source);
- fclose(fp2);
- return;
- }
- do
- {
- num = fread(buffer,1024,fp);
- if( num<1 ) break;
- fwrite(buffer,num,fp2);
- }
- while( !feof(fp) );
- fclose(fp);
- }
- }
-
- fclose(fp2);
- }
-
- /*---------------------------------------------------------------------------*/
-
- get_filename(source)
- {
- filestruct = SplitFileName(source);
- sprintf(newdir,"%s%s",filestruct.name,filestruct.ext);
- return newdir;
- }
-
-
- main(argc,argv)
- {
- if( defined(_OS2_) )
- {
- printf("This script does not yet support OS/2.\n");
- exit(EXIT_FAILURE);
- }
-
- parse_command_line(argc,argv);
-
- tar_dir = 0;
- if( !strcmp(target,".") )
- {
- if( defined(_NWNLM_) )
- strcat(target,"/");
- else
- strcat(target,"\\");
- tarfiles = NULL;
- } else tarfiles = Directory(target);
-
- if( tarfiles==NULL )
- {
- if( !strcmp(target,".\\") ) tar_dir = 1;
- if( isalpha(target[0]) && target[1]==':' &&
- (target[2]=='\0' ||
- ((target[2]=='/' || target[2]=='\\') && target[3]=='\0') ) )
- tar_dir = 1;
- } else {
- if( GetArraySpan(tarfiles)>0 )
- {
- // This is the case where the user typed something like : copy *.txt *.bak
- printf("Cannot copy file(s) to multiple destinations.\n");
- exit(EXIT_FAILURE);
- }
- strcpy(target,tarfiles[0].name);
- if( tarfiles[0].attrib & _A_SUBDIR )
- {
- tar_dir = 1;
- strcat(target,"\\");
- }
- }
-
- if( num_source==1 )
- {
- files = Directory(source[0]);
- if( files==NULL )
- {
- printf("No such file or directory.\n");
- exit(EXIT_FAILURE);
- }
- // If multiple file move, the target must be a directory, otherwise just copy
- // the old file to the new one.
- if( GetArraySpan(files)>0 )
- {
- if( !tar_dir )
- {
- copy_multiple(target); exit(EXIT_SUCCESS);
- }
-
- for( i=0;i<=GetArraySpan(files);i++ )
- {
- if( (files[i].attrib & _A_SUBDIR)==0 )
- {
- strcpy(tmp,target);
- strcat(tmp,get_filename(files[i].name));
- copy_file(files[i].name,tmp);
- }
- }
- } else {
- if( tar_dir )
- {
- sprintf(tmp,"%s%s",target,get_filename(files[0].name));
- } else {
- strcpy(tmp,target);
- }
- copy_file(files[0].name,tmp);
- }
- } else {
- // In this case, we copy multiple files into a single file, concatenating them
- if( tar_dir )
- {
- sprintf(tmp,"%s%s",target,get_filename(files[0].name));
- } else {
- strcpy(tmp,target);
- }
- copy_multiple(tmp);
- }
- }
-